package org.pz.service;

import org.pz.component.ScheduleTaskCollections;
import lombok.extern.slf4j.Slf4j;
import org.pz.entity.MallResult;
import org.pz.job.BeanTaskJob;
import org.pz.utils.TaskUtil;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;

@Slf4j
@Service
public class QuartzServiceImpl implements QuartzService {

    @Autowired
    private Scheduler scheduler;

    @Autowired
    private ScheduleTaskCollections scheduleTaskCollections;

    private final String trigger_pre = "trigger_";

    /**
     *
     * */
    @Override
    public MallResult addCronJob(String jobName, String cron, String code) {

        //1. 创建一个 jobkey
        JobKey jobKey = JobKey.jobKey(jobName);
        try {
            if(scheduler.checkExists(jobKey)){
                return MallResult.error("【添加定时任务】该作业名称已存在");
            }

            //2. 构建 jobDataMap
            HashMap<String, Object> jobMap = new HashMap<>();
            jobMap.put(TaskUtil.JOB_CODE, code);
            jobMap.put(TaskUtil.SCHEDULE_TASKS, scheduleTaskCollections);

            //3. 构建 jobDetail
            JobDetail jobDetail = JobBuilder.newJob(BeanTaskJob.class)
                    .withIdentity(jobKey)
                    .withDescription(jobName)
                    .storeDurably()
                    .setJobData(new JobDataMap(jobMap))
                    .build();

            //4. 根据 cron 表达式创建定时构造器
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);

            //5. 构建 trigger
            CronTrigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(trigger_pre + jobName)
                    .withSchedule(cronScheduleBuilder)
                    .build();

            //6. 启动调度
            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();

            log.info("创建调度任务 {} 成功！", jobName);

        } catch (SchedulerException e) {
            return MallResult.error("创建定时任务失败！原因：" + e.getMessage());
        }

        return MallResult.success();
    }

    @Override
    public MallResult updateCronJob(String jobName, String cron) {
        TriggerKey triggerKey = TriggerKey.triggerKey(trigger_pre + jobName);

        CronScheduleBuilder cronSchedule = CronScheduleBuilder.cronSchedule(cron);
        try {
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronSchedule).build();
            scheduler.rescheduleJob(triggerKey, trigger);

            log.info("修改调度任务 {} 成功！", jobName);

        } catch (SchedulerException e) {
            log.error("修改定时任务失败！");
            return MallResult.error("修改定时任务失败！");
        }

        return MallResult.success("更新定时任务成功！");
    }

    @Override
    public MallResult pauseCronJob(String jobName) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(trigger_pre + jobName);
            JobKey jobKey = JobKey.jobKey(jobName);

            // 检查作业和触发器是否存在
            if (!scheduler.checkExists(jobKey) || !scheduler.checkExists(triggerKey)) {
                return MallResult.error("作业或触发器不存在");
            }

            // 暂停触发器
            scheduler.pauseTrigger(triggerKey);

            log.info("暂停调度任务 {} ！", jobName);

            return MallResult.success("暂停定时任务成功！");
        } catch (Exception e) {
            return MallResult.error("暂停定时任务失败，原因是：" + e.getMessage());
        }
    }

    @Override
    public MallResult resumeCronJob(String jobName) {
        try {
            // 构建触发器key
            TriggerKey triggerKey = TriggerKey.triggerKey(trigger_pre + jobName);
            // 恢复触发器
            scheduler.resumeTrigger(triggerKey);

            log.info("唤醒调度任务 {} ", jobName);

            return MallResult.success("唤醒定时任务成功！");
        } catch (Exception e) {
            return MallResult.error("唤醒定时任务失败，原因是：" + e.getMessage());
        }
    }

    @Override
    public MallResult deleteCronJob(String jobName) {
        try {
            JobKey jobKey = JobKey.jobKey(jobName);
            TriggerKey triggerKey = TriggerKey.triggerKey(trigger_pre + jobName);

            if (!scheduler.checkExists(jobKey) ||!scheduler.checkExists(triggerKey)) {
                return MallResult.error("【删除定时任务】作业或触发器不存在");
            }

            //移除定时任务
            scheduler.unscheduleJob(triggerKey);
            scheduler.deleteJob(jobKey);

            log.info("删除调度任务 {} ！", jobName);

            return MallResult.success("删除定时任务成功！" + jobName);
        } catch (Exception e) {
            return MallResult.error("删除定时任务失败，原因为：" + e.getMessage());
        }
    }
}
